package prototype;

/**
 * 引用
 */
class I implements Cloneable{
    int b = 1;

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

/**
 * 浅克隆
 */
class Person implements Cloneable{
    int a;

    I i = new I();

    @Override
    public Object clone() throws CloneNotSupportedException {
        Person p = (Person) super.clone();
        /**
         * String str = "admin"
         * str被克隆以后虽然地址相同但是如果被克隆的str发生改变只是引用改到了新引用，它不会改原来的引用。注意是改的引用。
         * new String() 堆里面的是引用指向常量池。
         */
        p.i = (I) i.clone(); // 如果不加这句就是浅克隆加上就深克隆，深克隆需要把内部引用在克隆的时候都克隆一下。

        return p;
    }
}

public class Prototype {
    public static void main(String[] args) throws CloneNotSupportedException {
        System.out.println("prototype");

        Person p = new Person();
        Person p2 = (Person) p.clone();
        p.i.b = 11;
        System.out.println(p2.i.b );

        // String 是对象它如果在内部是不需要深克隆的 因为它在常量池里面，没有才创建有了就共享。但如果是 new String是需要深克隆的。
        // StringBuilder 不支持clone 需要内容复制出来在创建一个sb

    }
}
